SurfaceFlinger是GUI系统的核心服务,它主要负责图层的合成任务,同时它为每个应用程序维护一个Client,Client又是由多个Layer组成,Layer对应应用端的Window,这样SurfaceFlinger就能通过Layer来明白各个应用的绘图需求,从而将其合成显示。本篇将从SurfaceFlinger的角度来分析系统是如何通过Layer来管理绘图缓冲区。
缓冲队列
绘图缓冲区是通过BufferQueeu进行管理的,它是一个缓冲区队列,从生产消费的角度来说它同时为消费者和生产者,这里看看它的结构便可以知道
1 | class BufferQueue : public BnGraphicBufferProducer, |
BufferQueue同时是一个Binder,因此它也就具有跨进程的能力。本篇将会根据具体的使用来分析BufferQueue是如何同时作为消费者和生产者的。
BufferQueue的构成
BufferQueue内部是一个BufferSlot数组,大小为32,BufferSlot即Buffer槽用来描述一块缓冲区,需要注意的是BufferQueue在初始情况下并未分配缓冲区,只有当用户进行申请时才真正的分配缓冲区。一个缓冲区一旦被分配它便具有了状态,分别是:
FREE 表明该Buffer空闲,可以dequeue被生产者使用,此时它的拥有者为BufferQueue。
DEQUEUED 表示该Buffer已经被生产者dequeue,但还未入队或者取消,此时生产者是它的拥有者
QUEUED 表明这个Buffer已经被生产者填充好内容,等待消费者进行消费,此时它的拥有者为BufferQueue
ACQUIRED 表示该Buffer块被消费者获取到,此时消费者作为其拥有者。
1 | enum BufferState { |
BufferQueue作为消费者
View在第一次进行绘制时会从WMS请求一个Surface绘图表面,这个绘图表面实际上会通过IGrpahicBufferProducer来请求绘图缓冲区,它实际上是一个IBinder Client,它的服务端即BufferQueue是在为WMS对应的Window对象创建SF端的Layer对象时创建
1 | void Layer::onFirstRef() { |
这里的SurfaceTextureLayer是BufferQueue的子类,它在Layer对象被创建后第一次引用时创建。
1 | status_t SurfaceFlinger::createNormalLayer(const sp<Client>& client, |
可以看到Layer被创建后,通过getBufferQueue得到该缓冲队列,这个队列是以一个Binder代理返回给应用端的,应用端最终是通过该BufferQueue来请求缓冲区,从而通过该缓冲区构造SkCanvas最终提交给上层使用的。从这个角度来讲BufferQueue是作为生产者的。